#This script
## 1) pulls raw data from the NGHIS API, 
## 2) crosswalks the data to modern census boundaries
## 3) cleans data and calculates derivative statistics (e.g. percents, means)

#To run this, you will need:
## a National Historical GIS account (https://www.nhgis.org/)
## an IPUMPS API key (https://developer.ipums.org/docs/v2/get-started/)
## crosswalk files from the Brown Longitudinal Tract Database (https://s4.ad.brown.edu/projects/diversity/researcher/LTDB.htm)

if (!require(dplyr)) install.packages("dplyr")
if (!require(here)) install.packages("here")
if (!require(ipumsr)) install.packages("ipumsr")
if (!require(purrr)) install.packages("purrr")

library(dplyr)
library(here)
library(ipumsr)
library(purrr)


#set working directory & general attributes
here::i_am("02_data_historic/data_2020to2010tracts.R")
year <- "2020"
inflation <- 1

#set API key (to get one: https://account.ipums.org/api_keys)
my_key <- "your key here"
set_ipums_api_key(my_key)

#see metadata for relevant parameters
metadata <- get_metadata_nhgis(dataset = "2016_2020_ACS5a")


#pulling data from the IPUMS API
##define the data to extract
ds <- define_extract_agg(
  collection = "nhgis",
  description = "Gentrification map data, 2020 block groups",
  datasets = ds_spec("2016_2020_ACS5a",
                     data_tables = c("B01003", "B02001", "B03003", "B11001", 
                                     "B15003", "C17002","B19025", "C24010", 
                                     "B25001", "B25002", "B25003", "B25038",
                                     "B25060", "B25082"),
                     geog_levels = "blck_grp"
  ),
  geographic_extents = "*"
)

##submit the API and download results
extract <- submit_extract(ds)
wait_for_extract(extract)   
filepath <- download_extract(extract)


#load, sort, and clean data
##define variables
variables <- c(
  Adults_sum = "AMRZE001",
  Asian_sum = "AMPWE005",
  Black_sum = "AMPWE003",
  ConRent_agg = "AMVVE001",
  Ed_Bach_sum = "AMRZE022",
  Ed_Doctorate_sum = "AMRZE025",
  Ed_Masters_sum = "AMRZE023",
  Ed_ProfDegree_sum = "AMRZE024",
  Employed_sum = "AMZOE001",
  HHIncome_agg = "AMR9E001",
  Hispanic_sum = "AMP4E003",
  Households_sum = "AMQSE001",
  HouseUnits_sum = "AMUDE001",
  HouseValue_agg = "AMWGE001",
  HouseValue_Mortgaged_agg = "AMWGE002",
  HUOccupied_sum = "AMUEE002",
  HUOwner_sum = "AMUFE002",
  HURenter_sum = "AMUFE003",
  HUVacant_sum = "AMUEE003",
  Owner_MovedIn_2to5yrs_sum = "AMVBE004",
  Owner_MovedIn_5to10yrs_sum= "AMVBE005",
  Owner_MovedIn_under1yr_sum = "AMVBE003",
  Renter_MovedIn_2to5yrs_sum = "AMVBE011",
  Renter_MovedIn_5to10yrs_sum = "AMVBE012",
  Renter_MovedIn_under1yr_sum = "AMVBE010",
  Multi_sum = "AMPWE009",
  Occ_MBSA_F_sum = "AMZOE039",
  Occ_MBSA_M_sum = "AMZOE003",
  Other_sum = "AMPWE007",
  Population_sum = "AMPVE001",
  Pov_50to99_sum2020 = "AMZME003",
  Pov_under50_sum = "AMZME002",
  White_sum = "AMPWE002"
)

##query and load data into dataframe
data <- read_nhgis(filepath) %>%
  select(GISJOIN, all_of(variables)) 
data <- data %>% select(GISJOIN, sort(setdiff(names(.), "GISJOIN")))


#crosswalk the data to 2010 boundaries
##load crosswalk from IPUMS API
url <- "https://api.ipums.org/supplemental-data/nhgis/crosswalks/nhgis_bg2020_tr2010.zip"
download.file(url, "nhgis_bg2020_tr2010.zip", headers = c(Authorization = my_key))
crosswalks <- read_nhgis("nhgis_bg2020_tr2010.zip")

##join with data
data <- data %>% rename(bg2020gj = GISJOIN)
data <- left_join(crosswalks, data, by = "bg2020gj")
rm(crosswalks)

##weight source data for new boundaries
data <- within(data, {
  Adults_sum <- Adults_sum * wt_pop
  Asian_sum <- Asian_sum * wt_pop
  Black_sum <- Black_sum * wt_pop
  ConRent_agg <- ConRent_agg * wt_renthu
  Ed_Bach_sum <- Ed_Bach_sum * wt_adult
  Ed_Masters_sum <- Ed_Masters_sum * wt_adult
  Ed_ProfDegree_sum <- Ed_ProfDegree_sum * wt_adult
  Ed_Doctorate_sum <- Ed_Doctorate_sum * wt_adult
  Employed_sum <- Employed_sum * wt_pop
  HHIncome_agg <- HHIncome_agg * wt_hh
  Hispanic_sum <- Hispanic_sum * wt_pop
  Households_sum <- Households_sum * wt_hh
  HouseUnits_sum <- HouseUnits_sum * wt_hu
  HouseValue_agg <- HouseValue_agg * wt_ownhu
  HouseValue_Mortgaged_agg <- HouseValue_Mortgaged_agg * wt_ownhu
  HUOccupied_sum <- HUOccupied_sum * wt_ownhu
  HUOwner_sum <- HUOwner_sum * wt_hu
  HURenter_sum <- HURenter_sum * wt_renthu
  HUVacant_sum <- HUVacant_sum * wt_hu
  Owner_MovedIn_2to5yrs_sum <- Owner_MovedIn_2to5yrs_sum * wt_ownhu
  Owner_MovedIn_5to10yrs_sum <- Owner_MovedIn_5to10yrs_sum * wt_ownhu
  Owner_MovedIn_under1yr_sum <- Owner_MovedIn_under1yr_sum * wt_ownhu
  Renter_MovedIn_2to5yrs_sum <- Renter_MovedIn_2to5yrs_sum * wt_renthu
  Renter_MovedIn_5to10yrs_sum <- Renter_MovedIn_5to10yrs_sum * wt_renthu
  Renter_MovedIn_under1yr_sum <- Renter_MovedIn_under1yr_sum * wt_renthu
  Multi_sum <- Multi_sum * wt_pop
  Occ_MBSA_F_sum <- Occ_MBSA_F_sum * wt_pop
  Occ_MBSA_M_sum <- Occ_MBSA_M_sum * wt_pop
  Other_sum <- Other_sum * wt_pop
  Population_sum <- Population_sum * wt_pop
  Pov_under50_sum <- Pov_under50_sum * wt_pop
  Pov_50to99_sum2020 <- Pov_50to99_sum2020 * wt_pop
  White_sum <- White_sum * wt_pop
})

##calculate additional categories from components
data <- within(data, {
  Bach_sum <- Ed_Bach_sum + Ed_Masters_sum + Ed_ProfDegree_sum + Ed_Doctorate_sum
  MovedIn_under10yrs_sum <- Owner_MovedIn_under1yr_sum + Owner_MovedIn_2to5yrs_sum + 
    Owner_MovedIn_5to10yrs_sum + Renter_MovedIn_under1yr_sum + 
    Renter_MovedIn_2to5yrs_sum + Renter_MovedIn_5to10yrs_sum
  Poverty_sum <- Pov_under50_sum + Pov_50to99_sum2020
  WhiteCollar_sum <- Occ_MBSA_F_sum + Occ_MBSA_M_sum
})

##name variable selections
variable_names <- c(
  "Adults_sum",
  "Asian_sum",
  "Bach_sum",
  "Black_sum",
  "ConRent_agg",
  "Employed_sum",
  "HHIncome_agg",
  "Hispanic_sum",
  "Households_sum",
  "HouseUnits_sum",
  "HouseValue_agg",
  "HouseValue_Mortgaged_agg",
  "HUOccupied_sum",
  "HUOwner_sum",
  "HURenter_sum",
  "HUVacant_sum",
  "MovedIn_under10yrs_sum",
  "Multi_sum",
  "Other_sum",
  "Population_sum",
  "Poverty_sum",
  "White_sum", 
  "WhiteCollar_sum"
)

##pivot by tract boundary
data <- data %>% select(all_of(c("tr2010gj", variable_names)))
data <- data %>% 
  group_by(tr2010gj) %>%
  summarize(across(all_of(variable_names), sum))


# Calculate derivative metrics at the tract scale
## Define functions to exclude incorrect data and low-population tracts
divide_pop <- Vectorize(function(numerator, denominator) {
  if (!is.na(numerator) && !is.na(denominator) && numerator < denominator && denominator >= 100) {
    return(numerator / denominator)
  } else {
    return(NA)
  }
})

divide_units <- Vectorize(function(numerator, denominator) {
  if (!is.na(numerator) && !is.na(denominator) && numerator < denominator && denominator >= 10) {
    return(numerator / denominator)
  } else {
    return(NA)
  }
})

divide_value <- Vectorize(function(numerator, denominator) {
  if (!is.na(numerator) && !is.na(denominator) && denominator >= 10) {
    return(numerator / denominator)
  } else {
    return(NA)
  }
})

##apply functions
data <- within(data, {
  ## Socioeconomic variables
  Bach_pct <- divide_pop(Bach_sum, Adults_sum) * 100
  ConRent_mean <- divide_value(ConRent_agg, HURenter_sum) * inflation
  HHIncome_mean <- divide_value(HHIncome_agg, Households_sum) * inflation
  HouseValue_mean <- divide_value(HouseValue_agg, HUOwner_sum) * inflation
  HouseValue_Mortgaged_mean <- divide_value(HouseValue_Mortgaged_agg, HUOwner_sum) * inflation
  HUOwner_pct <- divide_units(HUOwner_sum, HouseUnits_sum) * 100
  HURenter_pct <- divide_units(HURenter_sum, HouseUnits_sum) * 100
  HUVacant_pct <- divide_units(HUVacant_sum, HouseUnits_sum) * 100
  MovedIn_under10yrs_pct <- divide_units(MovedIn_under10yrs_sum, HUOccupied_sum) * 100
  Poverty_pct <- divide_pop(Poverty_sum, Population_sum) * 100
  WhiteCollar_pct <- divide_pop(WhiteCollar_sum, Employed_sum) * 100
  
  ## Racial/ethnic variables
  Asian_pct <- divide_pop(Asian_sum, Population_sum) * 100 
  Black_pct <- divide_pop(Black_sum, Population_sum) * 100 
  Hispanic_pct <- divide_pop(Hispanic_sum, Population_sum) * 100 
  Multi_pct <- divide_pop(Multi_sum, Population_sum) * 100 
  Other_pct <- divide_pop(Other_sum, Population_sum) * 100 
  White_pct <- divide_pop(White_sum, Population_sum) * 100 
})

## Residential diversity variables
data$Elocal <- ifelse((data$Population_sum >= 100),
                      ((data$White_sum /  data$Population_sum) * log(1 / (data$White_sum / data$Population_sum)) +
                         (data$Black_sum / data$Population_sum) * log(1 / (data$Black_sum / data$Population_sum)) +
                         (data$Asian_sum / data$Population_sum) * log(1 / (data$Asian_sum / data$Population_sum)) +
                         (data$Other_sum / data$Population_sum) * log(1 / (data$Other_sum / data$Population_sum))),
                      NA)

#final cleanup and save
##sort data
data <- data %>% select(tr2010gj, sort(setdiff(names(.), "tr2010gj")))

##name processed data
data <- data %>%
  rename_with(
    ~ifelse(. == "tr2010gj", ., paste0(., "_", year)),
    .cols = everything()
  )

##archive original data
file.rename(filepath, paste0("nhgis_", year, ".zip" ))

##save cleaned data
filename <- paste0("tractdata_", year, "_2010tr.csv")
write.csv(data, file = filename, na="", row.names = FALSE)

